# -*-coding: utf-8 -*-
# by zw on 2018/2/24

import paramiko, time

import logging

from sanic.response import HTTPResponse
from sanic import response
from utils.mongo import get_salt_run_history_collection, get_app_config_collection
from utils.time_kit import timestamp_2_datetime_str
from sanic import Blueprint
from settings import config

bp = Blueprint('salt_ssh', url_prefix='/salt_ssh')
_logger = logging.getLogger(__name__)

hostname = config['saltmaster_hostname']
port = config['saltmaster_port']
username = config['saltmaster_username']
password = config['saltmaster_password']


def sshclient_execmd(hostname, port, username, password, execmd):
    paramiko.util.log_to_file("../logs/paramiko.log")

    s = paramiko.SSHClient()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    s.connect(hostname=hostname, port=port, username=username, password=password)
    stdin, stdout, stderr = s.exec_command(execmd)
    stdin.write("Y")  # Generally speaking, the first connection, need a simple interaction.
    out = stdout.read()
    s.close()
    return out


@bp.route("/salt-run", {"GET"})
async def salt_run(request):
    app_name, deploy_name = "", ""
    try:
        app_name = request.raw_args['app_name']
        deploy_name = request.raw_args['deploy_name']
        is_test = int(request.raw_args['is_test'])
        version = request.raw_args.get("version", "")
        deploy_type = request.raw_args.get("deploy_type", "")

    except Exception as e:
        _logger.exception("url %s exception %s app_name %s env %s  deploy_name " % (
            request.url, e, app_name, deploy_name))
        return HTTPResponse(body_bytes="")

    app_config = get_app_config_collection().find_one({"app_name": app_name})

    deploys = app_config.get(deploy_type, [])

    exc = ""
    for ii, _ in enumerate(deploys):
        if deploys[ii][0] == deploy_name:
            exc = deploys[ii][1]
            if is_test:
                exc = exc.replace("False", "True")
                exc = exc.replace("false", "true")

            break

    if "%s" in exc:
        exc = exc % version
    ctime = int(time.time())
    get_salt_run_history_collection().insert(
        {"app_name": app_name, "exc": exc, "is_test": is_test, "deploy_name": deploy_name, "ctime": ctime})

    rs = sshclient_execmd(hostname, port, username, password, exc)

    get_salt_run_history_collection().update_many(
        {"app_name": app_name, "deploy_name": deploy_name, "ctime": ctime},
        {"$set": {"rs": rs, "utime": int(time.time())}})
    rs = exc.encode("utf-8") + b"\n" + rs
    return HTTPResponse(body_bytes=rs)


@bp.route("/salt-run-history", {"GET"})
async def salt_run_history(request):
    app_name, deploy_name = "", ""
    try:
        app_name = request.raw_args['app_name']
        deploy_name = request.raw_args['deploy_name']
        is_test = int(request.raw_args['is_test'])
        skip = int(request.raw_args.get("skip", 0))

    except Exception as e:
        _logger.exception("url %s exception %s app_name %s env %s  deploy_name " % (
            request.url, e, app_name, deploy_name))
        return HTTPResponse(body_bytes="")

    rs = get_salt_run_history_collection().find(
        {"app_name": app_name, "deploy_name": deploy_name, },
        {"_id": 0}
    ).sort([("ctime", -1)]).skip(skip).limit(1).to_list(None)
    data = {}
    if rs:
        data = rs[0]
        _s = "部署开始时间:%s\n部署结束时间:%s\n" % (
            timestamp_2_datetime_str(data['ctime']), timestamp_2_datetime_str(data.get("utime", 0)))
        _s += "部署脚本: %s\n" % data['exc']

        data['rs'] = _s + data.get("rs", b"").decode("utf-8")
    return response.json({"code": 0, "message": "", "data": data})
